<?php

namespace App\Http\Services;

use App\Http\Model\CrossRoomPkRecord;
use App\Http\Model\Friends;
use App\Http\Model\Hint;
use App\Http\Model\Room;
use App\Model\RoomRole;
use App\Http\Model\Mall;
use App\Http\Model\Union;
use App\Http\Model\UnionUser;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class CrossRoomPkService extends CommonServices
{
    protected $roomModel;//房间管理员表
    protected $service_msg;//系统消息推送
    protected $crossRoomPkModel;//pk发起记录
    protected $friendsModel;//关注列表
    protected $mall_model;//商品model
    protected $model_union_user;//公会用户model
    protected $model_union;//公会

    protected $crossRoomPkRedisList = 'CROSS:ROOM:PK:ALLIST'; //所有玩PK的房间列表 set CROSS:ROOM:PK:ALLIST=>roomID
    protected $crossRoomPkLockRedis = 'CROSS:ROOM:PK:LOCK:'; //确认邀请锁
    protected $crossRoomSendPkLockRedis = 'CROSS:ROOM:PK:SEND:LOCK:';//发送邀请锁
    protected $crossRoomPkRandLockRedis = 'CROSS:ROOM:PK:RAND:LOCK:';//发起随机邀请

    protected $crossRoomDayPointKey = 'CROSS:ROOM:DAYPOINT:'; //房间日榜贡献榜 CROSS:ROOM:DAYPOINT {value} {roomid}
    protected $crossRoomWeekPointKey = 'CROSS:ROOM:WEEKPOINT:'; //房间周榜贡献榜 CROSS:ROOM:WEEKPOINT {value} {roomid}
    protected $crossRoomWeekInRoomUserPointKey = 'CROSS:ROOM:WEEKUSERPOINT:'; //单个房间周榜用户参与贡献榜 CROSS:ROOM:WEEKUSERPOINT {value} {userId}
    protected $crossRoomPkRoomNowPointKey = 'CROSS:ROOM:PK:ROOMNOW:'; //房间实时榜用户参与贡献榜 CROSS:ROOM:WEEKUSERPOINT {value} {userId}
    
    protected $crossRoomUserDayPointKey = 'CROSS:ROOM:USER:DAYPOINT';//用户日贡献榜 CROSS:ROOM:USER:DAYPOINT {value} {roomid}
    protected $crossRoomUserWeekPointKey = 'CROSS:ROOM:USER:WEEKPOINT';//用户日贡献榜 CROSS:ROOM:USER:WEEKPOINT {value} {roomid}

    protected $crossRoomPkGetGiftUserPointKey = 'CROSS:ROOM:PK:GETGIFT:USER:ROOM:';//ZSET PK中收礼用户获得的贡献值 CROSS:ROOM:PK:GETGIFT:USER:ROOM 

    protected $crossRoomWinnerRoomCount = 'CROSS:ROOM:PK:WINNER:';//房间胜利次数 CROSS:ROOM:PK:WINNER:{roomid} => {count}
    protected $roomOpenListKey = 'ROOM:OPENLIST';//房间缓存
    protected $userPkSendGiftKey = 'CROSS:ROOM:PK:MISSION:SENDGITFUSER:';//用户送礼每日PK任务; CROSS:ROOM:PK:SENDGITF:USER:{userId}=>1;
    protected $missionPkAnchorKey = 'CROSS:ROOM:PK:MISSION:ANCHORWINPK:';//用户每日PK胜利任务缓存 CROSS:ROOM:PK:MISSION:ANCHORWINPK:{$userID}=>1
    protected $endPkRedisKey = 'CROSS:ROOM:PK:ENDPK:';//结束房间PK锁 CROSS:ROOM:PK:ENDPK:{recordId}
    protected $ranRoomTimes = 'CROSS:ROOM:PK:RAND:';//随机匹配房间次数缓存 CROSS:ROOM:PK:RAND:{ROOMID}=>1 

    protected $missionIcon;//任务图片

    protected $apiService;
    protected $userService;
    protected $roomService;


    protected $log = 'crossRoomPkGift';
    protected $error_log = 'error_crossRoomPkGift';
    public function __construct()
    {
        parent::__construct();
        $this->roomModel = new Room();
        $this->service_msg = new MsgServices();
        $this->crossRoomPkModel = new CrossRoomPkRecord();
        $this->friendsModel = new Friends();
        $this->apiService = new ApiServices();
        $this->mall_model = new Mall();
        $this->userService = new UserServices();
        $this->model_union_user = new UnionUser();
        $this->model_union = new Union();
        $this->roomService = new RoomServices();
        $this->missionIcon = [
            [
                'icon' => build_image('/icon/pk_gift.png'),
                'mission' => '在PK中完成一次送礼',
                'type' => 1,
                'is_complate' => 0,//1=已完成 0=未完成
                'is_get' => 0,//1=已领取 0=未领取
                'award_id' =>0,
                'desc' =>'',
                'gift_name' =>'',
            ],
            [
                'icon' => build_image('/icon/pk_mic.png'),
                'mission' => '上麦获得1次',
                'type' => 2,
                'is_complate' => 0,//1=已完成 0=未完成
                'is_get' => 0,//1=已领取 0=未领取
                'award_id' =>0,
                'desc' => '上麦时长满足1分钟',
                'gift_name' => '',
            ],
            [
                'icon' => build_image('/icon/pk_msg.png'),
                'mission' => 'pk中发言1次',
                'type' => 3,
                'is_complate' => 0,//1=已完成 0=未完成
                'is_get' => 0,//1=已领取 0=未领取
                'award_id' =>0,
                'desc' => '需大于10字',
                'gift_name' => '',
            ],
            [
                'icon' => build_image('/icon/pk_win.png'),
                'mission' => '取得1场pk胜利',
                'type' => 4,
                'is_complate' => 0,//1=已完成 0=未完成
                'is_get' => 0,//1=已领取 0=未领取
                'award_id' =>0,
                'desc' =>'',
                'gift_name' => '',
            ]
        ];
    }

    //根据userID查看是否是房间所属管理员
    public function checkRoomAdmin($userId, $roomId){
        $roleId = $this->roomModel->get_role($roomId, $userId);
        return $roleId;
    }

    //根据房间id获取房间类型是否是cbd
    public function checkCbdRoom($roomId){
        $isCbd = $this->roomModel->get_room_business_type($roomId);
        return $isCbd;
    }

    //发送邀请通知
    public function sendPkMsg($toRoomId, $roomId, $fromUserId, $type){
        do{
            $code = Hint::SUCCESS;
            $msg = 'OK';
            //自己房间不能邀请自己
            if($toRoomId == $roomId){
                $code = Hint::ERR_NORMAL;
                $msg = '同一房间不能邀请PK';
                break;
            }
            //查询发起者房间信息
            $roomInfo = $this->roomModel->get_room($roomId);
            //是否在PK中
            $pkIsset = $this->crossRoomPkModel->issetPkRecord($toRoomId,4,1);
            if(!empty($pkIsset)){
                $code = Hint::ERR_NORMAL;
                $msg = '等待PK结束';
                break;
            }
            //查询后台配置的PK时长
            $backSetInfo = $this->crossRoomPkModel->getPkMinutes();
            //时间是否在开启范围内
            $now = Carbon::now()->toTimeString();
            if(strtotime($now) < strtotime($backSetInfo['pk_start']) || strtotime($now) > strtotime($backSetInfo['pk_end'])){
                $code = Hint::ERR_NORMAL;
                $msg = '跨房pk开启时间：00:00:00-23:59:59';
                break;
            }
            $data = [
                'from_room_id' => $roomId,//发起人房间id
                'from_user_id' => $fromUserId,//发起用户id
                'to_room_id' => $toRoomId,//接收房间id
                'pk_all_time' => isset($backSetInfo['minutes']) ? $backSetInfo['minutes'] : 30,
                'send_status' => 0,//接收邀请状态 0=等待 1=已接受 2=管理拒绝 3=系统拒绝
                'type' => $type,//1定向 2=随机
                'created_at' => Carbon::now()->toDateTimeString()
            ];
            $insertId = $this->crossRoomPkModel->recordPk($data);
            //发送融云信息
            $msg = $this->service_msg->send_cross_pk_msg($toRoomId, $roomInfo, $insertId, $type);
            //给本房间发送已经发起PK状态
            $roomInfo = $this->roomModel->get_room($toRoomId);
            $our = $this->service_msg->our_cross_pk_msg($roomId, $roomInfo, $insertId, $type);
        }while (false);
        return compact('code','msg');
    }

    //发起随机pk
    public function sendRandPkMsg($roomId, $fromUserId, $type, $sendId=0){
        do{
            //发起PK的redis记录
            if(!Redis::SISMEMBER($$this->crossRoomPkRedisList,$roomId)){
                Redis::SADD($this->crossRoomPkRedisList,$roomId);
            }
            $code = Hint::SUCCESS;
            $msg = 'OK';
            //查询发起者房间信息
            $roomInfo = $this->roomModel->get_room($roomId);
            
            //查询后台配置的PK时长
            $backSetInfo = $this->crossRoomPkModel->getPkMinutes();
            //时间是否在开启范围内
            $now = Carbon::now()->toTimeString();
            if(strtotime($now) < strtotime($backSetInfo['pk_start']) || strtotime($now) > strtotime($backSetInfo['pk_end'])){
                $code = Hint::ERR_NORMAL;
                $msg = '跨房pk开启时间：00:00:00-23:59:59';
                break;
            }
            //自己是否在PK中
            $myPkIsset = $this->crossRoomPkModel->issetPkRecord($roomId,4,1);
            if(!empty($myPkIsset)){
                $code = Hint::ERR_NORMAL;
                $msg = '本房间正在PK进行中,无法匹配';
                break;
            }
            //获取随机房间id
            $toRoomId = $this->randRoom($roomId);
            if(!$toRoomId){
                //直接终止匹配因为3次都匹配到了自己
                Redis::DEL($this->ranRoomTimes.$roomId);
                //发送融云停止匹配
                $this->service_msg->confirm_cross_pk_msg($roomId, $roomInfo, 3, '00:00:00', '00:00:00', $v['id'], 2);
                break;
            }
            //对方是否在PK中
            $pkIsset = $this->crossRoomPkModel->issetPkRecord($toRoomId[0],4,1);
            if(!empty($pkIsset)){
                $toRoomId = $this->randRoom($roomId);
            }
            
            $data = [
                'from_room_id' => $roomId,//发起人房间id
                'from_user_id' => $fromUserId,//发起用户id
                'to_room_id' => $toRoomId[0],//接收房间id
                'pk_all_time' => isset($backSetInfo['minutes']) ? $backSetInfo['minutes'] : 30,
                'send_status' => 0,//接收邀请状态 0=等待 1=已接受 2=管理拒绝 3=系统拒绝
                'type' => $type,
            ];
            if(!empty($sendId)){
                $data['updated_at'] = Carbon::now()->toDateTimeString();
            }else{
                $data['created_at'] = Carbon::now()->toDateTimeString();
            }
            $insertId = $this->crossRoomPkModel->recordPk($data, $sendId);
            //发送融云信息
            $msg = $this->service_msg->send_cross_pk_msg($toRoomId[0], $roomInfo, $insertId, $type);
            if(empty($sendId)){
                //给本房间发送已经发起PK状态
                $roomInfo = $this->roomModel->get_room($roomId);
                $our = $this->service_msg->our_cross_pk_msg($roomId, $roomInfo, $insertId, $type);
            } 
        }while(false);
        return compact('code','msg');
    }

    //随机取room
    public function randRoom($roomId){
        $toRoomId = Redis::SRANDMEMBER($this->crossRoomPkRedisList,1);
        if($toRoomId[0] == $roomId){
            //防止死循环
            Redis::INCRBY($this->ranRoomTimes.$roomId,1);
            if(Redis::GET($this->ranRoomTimes.$roomId) >= 3){
                return false;
            }
            $toRoomId = $this->randRoom($roomId);
        }
        return $toRoomId;
    }

    //接收邀请通知
    public function confirmPkmsg($fromRoomId, $myRoomId, $myUserId, $type, $sendId){
        do{
            $code = Hint::SUCCESS;
            $msg = 'OK';
            $data = [];
            //事件防止多次发送确认
            $is_send = redis_lock($this->crossRoomPkLockRedis.$sendId,1);
            if(!$is_send){
                $code = Hint::ERR_NORMAL;
                $msg = '已发送通知';
                break;
            }
            //是否在PK中
            $roomMode = $this->roomModel->getRoomOpenList($myRoomId, 'roomMode');
            if($roomMode == 6){
                $code = Hint::ERR_NORMAL;
                $msg = '等待PK结束';
                break;
            }
            //获取邀请PK记录信息
            $invitePkInfo = $this->crossRoomPkModel->getPkInfo($sendId);
            //查看状态是否是取消状态
            if($invitePkInfo['send_status'] == 4){
                $code = Hint::ERR_NORMAL;
                $msg = 'pk已取消';
                break;
            }
            $now = Carbon::now()->toTimeString();
            //邀请时效
            $diffTime = Carbon::parse($now)->diffInMinutes($invitePkInfo['created_at']);
            if($diffTime >= 8){
                $code = Hint::ERR_NORMAL;
                $msg = 'pk邀请失效';
                break;
            }

            //查询后台配置的PK时长
            $backSetInfo = $this->crossRoomPkModel->getPkMinutes();
            //时间是否在开启范围内
            if(strtotime($now) < strtotime($backSetInfo['pk_start']) || strtotime($now) > strtotime($backSetInfo['pk_end'])){
                $code = Hint::ERR_NORMAL;
                $msg = 'PK暂未开始';
                $type = 3;//不在时间内默认系统拒绝
            }
            //查询接收者房间信息
            $roomInfo = $this->roomModel->get_room($myRoomId);
            $nowTime = Carbon::now()->toDateTimeString();
            $endTime = Carbon::parse($nowTime)->addMinutes($backSetInfo['minutes'])->toDateTimeString();
            if(in_array($type,[2,3,4])){
                $pk_status = 0; //type=2,3是拒绝不更改PK状态   
            }else{
                $pk_status = 4; //type=1代表接受pk状态改为PK中
                //更新对方和我方房间模式
                $this->crossRoomPkModel->upRoomModel($fromRoomId,$myRoomId);
                $this->roomModel->setRoomOpenListCache($fromRoomId,'roomMode',6);
                $this->roomModel->setRoomOpenListCache($myRoomId,'roomMode',6);
                //接受邀请后取消匹配池中数据
                Redis::SREM($this->crossRoomPkRedisList,$fromRoomId);
                Redis::SREM($this->crossRoomPkRedisList,$myRoomId);
            }
            //若随机匹配拒绝后再随机取另一个
            if($type == 2 && $invitePkInfo['type'] == 2){
                $this->sendRandPkMsg($invitePkInfo['from_room_id'],$invitePkInfo['from_user_id'], 2, $sendId);
            }else{
                $update = [
                    'to_user_id' => $myUserId,
                    'pk_status' => $pk_status,
                    'send_status' => $type, //1=接受 2=拒绝 3=系统拒绝
                    'pk_start_time' => $nowTime, //pk开始时间
                    'pk_end_time' => $endTime,//pk结束时间
                    'updated_at' => $nowTime,
                ];
                $this->crossRoomPkModel->upRecordPk($update,$sendId);
            }
            //返回开始时间-结束时间
            $data = [
                'pk_end_time' => $endTime,
                'pk_start_time' => $nowTime
            ];
            //发送消息
            $msg = $this->service_msg->confirm_cross_pk_msg($fromRoomId, $roomInfo, $type, $nowTime, $endTime, $sendId, $invitePkInfo['type']);
            //自己房间发送接收状态
            $fromInfo = $this->roomModel->get_room($fromRoomId);
            $this->service_msg->our_confirm_cross_pk_msg($myRoomId, $fromInfo, $type, $nowTime, $endTime, $sendId, $invitePkInfo['type']);
            
        }while(false);
        return compact('code','msg','data');
    }
    
    //取消pk
    public function pkCancel($sendId, $userID, $roomId){
        do{
            $code = Hint::SUCCESS;
            $msg = "ok";
            //查询PK记录
            $pkInfo = $this->crossRoomPkModel->getPkInfo($sendId);
            if(empty($pkInfo)){
                $code = Hint::ERR_NORMAL;
                $msg = '暂时未开启PK状态';
                break;
            }
            if($pkInfo['pk_status'] != 0){
                $code = Hint::ERR_NORMAL;
                $msg = 'pk已建立';
                break;
            }
            if($pkInfo['send_status'] != 0){
                $code = Hint::ERR_NORMAL;
                $msg = 'pk邀请已处理';
                break;
            }
            //防止多次操作
            redis_lock('CROSS:ROOM:PK:CANCLEPK:'.$sendId,10);
            $nowTime = Carbon::now()->toDateTimeString();
            $update = [
                'send_status' => 4,//取消PK状态
                'updated_at' => $nowTime,
            ];
            $this->crossRoomPkModel->upRecordPk($update,$sendId);
            //给我方人员发送取消邀请通知
            $this->service_msg->our_cancel_cross_pk_msg($roomId, $sendId);
        }while(false);
        return compact('code','msg');
    }

    //获取pk列表
    public function getPkList($userId, $roomId, $page, $limit){
        $pkList = Redis::SMEMBERS($this->crossRoomPkRedisList);
        //获取相互关注的用户id所在房间
        $friends = $this->friendsModel->get_follows($userId);
        if(!empty($friends)){
            $friends = array_column($friends,'user_id');
        }
        //查看这些用户在那个房间
        $roomList = $this->apiService->liveRooms($friends);
        if(!empty($roomList)){
            $finalArr = array_merge($roomList,$pkList);
        }else{
            $finalArr = $pkList;
        }
        $newData = [];
        if(!empty($finalArr)){
            //获取房间信息
            $roomArr = $this->crossRoomPkModel->get_room($page,$limit,$finalArr, $roomId);//房间信息
            foreach($roomArr as $k=>$v){
                $waitting = $this->crossRoomPkModel->issetWatting($v['room_id'], 0, 0); //房间是否匹配中
                $pkpoint = $this->crossRoomPkModel->getPkPoolData($v['room_id']);
                $newData[$k]['name'] = $v['name'];//房间名称
                $newData[$k]['room_id'] = $v['room_id'];
                $newData[$k]['image'] =  build_image($v['image']);//房间图片
                $newData[$k]['waitting'] = !empty($waitting) ? 1 : 0;//是否匹配中
                $newData[$k]['point'] = empty($pkpoint['point']) ? 0 : $pkpoint['point'];//房间贡献值
            }
            $point = array_column($newData,'point');
            array_multisort($point,SORT_DESC,$newData);
        }
        
        //查询系统配置的开始时间
        $backSetInfo = $this->crossRoomPkModel->getPkMinutes();
        //获取我的房间排名情况
        //今日开始-结束
        $today = Carbon::today()->toDateString();
        //一周开始-结束
        $weekStart = Carbon::today()->startOfWeek()->toDateString();
        $weekEnd =  Carbon::today()->endOfWeek()->toDateString();
        $roomDayRedisKey = $this->crossRoomDayPointKey.$today;

        $roomWeekRedisKey = $this->crossRoomWeekPointKey.$weekStart.'-'.$weekEnd;

        //系统PK开始时间
        $now = Carbon::now()->toTimeString();
        $sysPkStarTime = empty($backSetInfo) ? '16:00:00' : $backSetInfo['pk_start'];
        $sysPkStarTime = Carbon::parse($now)->diffInSeconds($sysPkStarTime,false);
        $sysPkendTime = empty($backSetInfo) ? '23:59:59' : $backSetInfo['pk_end'];
        $sysPkendTime = Carbon::parse($now)->diffInSeconds($sysPkendTime);

        //我当前房间所在的等级
        $myDayLevel = $this->myRoomLevel($roomId, 1, $roomDayRedisKey, $roomWeekRedisKey);
        $myWeekLevel = $this->myRoomLevel($roomId, 2, $roomDayRedisKey, $roomWeekRedisKey);
        //查询我房间是否在PK邀请中
        $waitting = $this->crossRoomPkModel->issetWatting($roomId, 0, 0); 
        $waittingInfo = null;
        $waittingTime = 0;
        $sendId = 0;
        if(!empty($waitting)){
            //获取对方房间头像名称
            $roomInfo = $this->roomModel->get_room($waitting['to_room_id']);
            $waittingInfo['name'] = $roomInfo['name'];
            $waittingInfo['room_id'] = $roomInfo['room_id'];
            $waittingInfo['image'] = $roomInfo['image'];
            //邀请等待时长
            $created_time = $waitting['created_at'];
            $waittingTime = Carbon::parse($now)->diffInSeconds($created_time);
            //邀请id
            if($waitting['to_room_id'] != $roomId){
                $sendId = $waitting['id'];
            }else{
                $waitting['type'] = 0;
            }
        }
    
        $myRoomRank['dayRank'] = empty($myDayLevel) ? 0 : $myDayLevel['level'];
        $myRoomRank['weekRank'] = empty($myWeekLevel) ? 0 : $myWeekLevel['level'];
        $returnData['list'] = $newData;
        $returnData['sys_pk_start'] = $sysPkStarTime < 0 ? 0 : $sysPkStarTime;
        $returnData['sys_pk_end'] =  $sysPkendTime;
        $returnData['watting_time'] = $waittingTime;
        $returnData['myRoomPkRank'] = $myRoomRank;
        $returnData['myRoomWaitting'] = $waittingInfo;
        $returnData['send_id'] = $sendId;
        $returnData['send_type'] = !isset($waitting['type']) ? 0 :$waitting['type'];
        return $returnData;
    }

    /**
     * 房间送礼物房间pk处理
     * giftNum 礼物数量
     * diamondTotal 每收礼用户的礼物价值总钻石数
     */
    public function crossRoomPkGiftForGameHandle($roomId, $fromUserId, $toUserIds, $giftNum, $diamondTotal,$gift_stream_id, $giftInfo){
//        write_log($this->log,'INFO 送礼数据',['roomId'=>$roomId,'from_user'=>$fromUserId,'touser'=>$toUserIds,'giftnum'=>$giftNum,'total'=>$diamondTotal,'stream_id'=>$gift_stream_id,'giftInfo'=>$giftInfo]);
        $now = time();
        do {
            if(empty($roomId)) {
                break;
            }
            if(empty($toUserIds)) {
                break;
            }
            if(empty($diamondTotal)) {
                break;
            }
            //获取缓存房间模式
            $roomMode = $this->roomModel->getRoomOpenList($roomId, 'roomMode');
            if($roomMode != 6) {
                break;
            }
            //获取房间是否在pk
            $pkInfo = $this->crossRoomPkModel->issetPkRecord($roomId);
            if(empty($pkInfo)){
                break;
            }
            //结束时间开始时间 
            $pkEndTime = $pkInfo['pk_end_time']; 
            $pkStartTime = $pkInfo['pk_start_time'];
            
            if(empty($pkStartTime) || empty($pkEndTime) || $now < strtotime($pkStartTime) || $now > strtotime($pkEndTime)){
                break;
            }

            //判断是否是首次送礼用户,触发首功消息推送
            $checkFirst = $this->crossRoomPkModel->checkFirstGift($fromUserId, $roomId, $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
            if($checkFirst == 0){
                //发送消息
                $roomdsIds = $this->crossRoomPkModel->issetPkRecord($roomId, 4, 1);
                $roomdsIds = [$roomdsIds['from_room_id'],$roomdsIds['to_room_id']];
                $msg = $this->service_msg->first_gift_cross_pk_msg($roomdsIds, $fromUserId, $giftInfo);
                write_log($this->log,'INFO 首功送礼推送',$msg);
            }
            //主播PK任务送礼任务每天第一次
            $isanchor = 0;
            $res = $this->model_union_user->userToUnion($fromUserId);
            if(!empty($res)){
                //查看公会是否认证
                $checkStatus = $this->model_union->getUnions([$res['un_id']]);
                if(isset($checkStatus[0]['authentication_status']) && $checkStatus[0]['authentication_status'] != 0){
                    $isanchor = 1;
                }
            }
            if(empty(Redis::get($this->userPkSendGiftKey.$fromUserId)) && !empty($isanchor)){
                $missList = $this->crossRoomPkModel->getMissionGift();
                $missList = array_column($missList,null,'mission_type');
                $insertMission = [
                    'user_id' => $fromUserId,
                    'mission_type' => 1,//任务类型 1=PK送礼 2=上麦任务 3=发言 4=PK胜利
                    'goods_id' => $missList[1]['goods_id'],
                    'send_status'=> 0,
                    'created_at' => Carbon::now()->toDateTimeString(),
                ];
                $this->crossRoomPkModel->insertMission($insertMission);
                //记录redis
                //计算结束当天所差秒数
                $now = Carbon::now()->toDateTimeString();
                $endDay = Carbon::now()->endOfDay()->toDateTimeString();
                $diffTime = Carbon::parse($now)->diffInSeconds($endDay);
                Redis::SET($this->userPkSendGiftKey.$fromUserId,1);
                Redis::EXPIRE($this->userPkSendGiftKey.$fromUserId,$diffTime);//当天结束时间秒数
                write_log($this->log,'INFO 完成送礼任务',$insertMission);
            }
            
            //送礼用户增加贡献值
            $sendUserTotal = $diamondTotal;
            //收礼用户贡献值
            $toUserTotal = $diamondTotal;
            //今日开始-结束
            $today = Carbon::today()->toDateString();
            //一周开始-结束
            $weekStart = Carbon::today()->startOfWeek()->toDateString();
            $weekEnd =  Carbon::today()->endOfWeek()->toDateString();
            //房间缓存key
            $roomDayRedisKey = $this->crossRoomDayPointKey.$today;
            $roomWeekRedisKey = $this->crossRoomWeekPointKey.$weekStart.'-'.$weekEnd;
            //房间内参与贡献用户周榜
            $crossRoomWeekUserInRoomPointKey = $this->crossRoomWeekInRoomUserPointKey.$roomId.":".$weekStart.'-'.$weekEnd;
            //PK中房间贡献实时榜
            $crossRoomPkRoomNowPointKey = $this->crossRoomPkRoomNowPointKey.$roomId;

            //用户缓存key
            $crossRoomUserDayPointKey = $this->crossRoomUserDayPointKey.$today;
            $crossRoomUserWeekPointKey = $this->crossRoomUserWeekPointKey.$weekStart.'-'.$weekEnd;
            //收礼用户缓存key
            $crossRoomPkGetGiftUserPointKey = $this->crossRoomPkGetGiftUserPointKey.$roomId;
            try{
                //表记录
                DB::beginTransaction();
                foreach($toUserIds as $k=> $v){
                    $roomTotal = $diamondTotal*2;
                    
                    if($checkFirst == 0 && $k==0){
                        $award = intval($diamondTotal * 1.3);
                        $insert['award_point'] = $award;
                        $roomTotal = intval(($diamondTotal*2) * 1.3);
                    }
                    $insert = [
                        'user_id' => $v,//收礼人
                        'from_user_id' => $fromUserId,//送礼人
                        'room_id' => $roomId,
                        'point' => $toUserTotal,
                        'room_point' => $roomTotal,
                        'gift_stream_id' => isset($gift_stream_id[0]) ? $gift_stream_id[0] : $gift_stream_id,
                        'create_timesamp' => time(),
                        'created_at' => Carbon::now()->toDateTimeString(),
                    ];
                    $this->crossRoomPkModel->insetRecord($insert);
                    //用户缓存
                    $this->redisSaveUserData($checkFirst, $k, $diamondTotal, $sendUserTotal, $crossRoomUserDayPointKey, $fromUserId, $crossRoomUserWeekPointKey, $v, $crossRoomWeekUserInRoomPointKey, $crossRoomPkRoomNowPointKey, $pkInfo['pk_end_time'],$crossRoomPkGetGiftUserPointKey);

                    $this->redisSaveRoomData($roomDayRedisKey, $roomTotal, $roomId, $roomWeekRedisKey);
                    
                    
                }
                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();
                write_log($this->error_log,'ERROR 数据处理失败',['msg'=>$e->getMessage(),'line'=>$e->getLine()]);
                break;
            }
            //通知房间目前房间实时排名情况
            $this->sendNowRoomPkInfo($roomId, $pkInfo);

        }while(false);
    }

    /**
     * 缓存用户排行榜数据
     *
     * @param [type] $checkFirst 是否是首次送礼
     * @param [type] $k  循环次数为了实现用户第一次送礼并且是第一个人时候
     * @param [type] $diamondTotal 送礼总钻石
     * @param [type] $sendUserTotal 赠送用户总钻石
     * @param [type] $crossRoomUserDayPointKey 用户总榜日榜贡献缓存
     * @param [type] $fromUserId 送礼人
     * @param [type] $crossRoomUserWeekPointKey 用户周榜贡献缓存
     * @param [type] $v 收礼人
     * @param [type] $crossRoomWeekUserPointKey 单个房间参与用户周榜缓存
     * @param [type] $crossRoomPkRoomNowPointKey 房间实时贡献用户榜
     * @return void
     */
    public function redisSaveUserData($checkFirst, $key, $diamondTotal, $sendUserTotal, $crossRoomUserDayPointKey, $fromUserId, $crossRoomUserWeekPointKey, $toUserId, $crossRoomWeekUserInRoomPointKey, $crossRoomPkRoomNowPointKey, $pkEndTime,$crossRoomPkGetGiftUserPointKey){
        if($checkFirst == 0 && $key==0){
            $award = intval($diamondTotal * 1.3);
            $sendUserTotal = $sendUserTotal + $award;
        }else{
            $sendUserTotal = $diamondTotal;
        }
        //送礼用户
        if(Redis::EXISTS($crossRoomUserDayPointKey)){
            Redis::ZINCRBY($crossRoomUserDayPointKey,$sendUserTotal,$fromUserId);//送礼人
        }else{
            Redis::ZINCRBY($crossRoomUserDayPointKey,$sendUserTotal,$fromUserId);//送礼人
            Redis::EXPIRE($crossRoomUserDayPointKey,86400);//1天
        }
        //用户周榜
        if(Redis::EXISTS($crossRoomUserWeekPointKey)){
            Redis::ZINCRBY($crossRoomUserWeekPointKey,$sendUserTotal,$fromUserId);//送礼人
        }else{
            Redis::ZINCRBY($crossRoomUserWeekPointKey,$sendUserTotal,$fromUserId);//送礼人
            Redis::EXPIRE($crossRoomUserWeekPointKey,7*86400);//7天
        }

        //单房间内参与用户周榜更新
        if(Redis::EXISTS($crossRoomWeekUserInRoomPointKey)){
            Redis::ZINCRBY($crossRoomWeekUserInRoomPointKey,$sendUserTotal,$fromUserId);//送礼人
        }else{
            Redis::ZINCRBY($crossRoomWeekUserInRoomPointKey,$sendUserTotal,$fromUserId);//送礼人
            Redis::EXPIRE($crossRoomUserWeekPointKey,7*86400);//7天
        }

        //用户房间实时贡献榜
        if(Redis::EXISTS($crossRoomPkRoomNowPointKey)){
            Redis::ZINCRBY($crossRoomPkRoomNowPointKey,$sendUserTotal,$fromUserId);//送礼人
        }else{
            Redis::ZINCRBY($crossRoomPkRoomNowPointKey,$sendUserTotal,$fromUserId);//送礼人
            $now = Carbon::now()->toDateTimeString();
            $diffTime = Carbon::parse($now)->diffInSeconds($pkEndTime);
            Redis::EXPIRE($crossRoomPkRoomNowPointKey,$diffTime);//pk期间内
        }

        //收礼用户
        if(Redis::EXISTS($crossRoomPkGetGiftUserPointKey)){
            Redis::ZINCRBY($crossRoomPkGetGiftUserPointKey,$diamondTotal,$toUserId);//收礼人
        }else{
            Redis::ZINCRBY($crossRoomPkGetGiftUserPointKey,$diamondTotal,$toUserId);//收礼人
            $now = Carbon::now()->toDateTimeString();
            $diffTime = Carbon::parse($now)->diffInSeconds($pkEndTime);
            Redis::EXPIRE($crossRoomPkGetGiftUserPointKey, $diffTime);//pk结束时间
        }
    }
    
    //通知房间目前实时PK排名情况
    public function sendNowRoomPkInfo($roomId, $pkInfo){
        //获取对方房间下目前排名情况
        if($pkInfo['from_room_id'] == $roomId){
            $otherRoomId = $pkInfo['to_room_id'];   
        }else{
            $otherRoomId = $pkInfo['from_room_id'];
        }
        $mydata = $this->getGiftRank($roomId, $otherRoomId, $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
        //发送融云信息
        $msg = $this->service_msg->send_now_cross_pk_msg($roomId, $mydata);
        //对方融云
        $otherData = $this->getGiftRank($otherRoomId, $roomId, $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
        $otherMsg = $this->service_msg->send_now_cross_pk_msg($otherRoomId, $otherData);
        write_log($this->log,"INFO 发送实时房间排名变化",['status'=>$msg,'mydata'=>$mydata,'other'=>$otherData]);
    }

    //获取房间pk
    public function getGiftRank($roomId, $otherRoomId, $pkStart, $pkEnd){
        //获取当前房间下榜单前三用户
        $selfRankList = Redis::zrevrangebyscore( $this->crossRoomPkRoomNowPointKey.$roomId,'+inf','-inf',['withscores'=>true , 'limit'=>[0,3]]);
        $selfRank = [];
        if(!empty($selfRankList)){
            foreach($selfRankList as $k=>$v){
                //用户信息
                $userInfo = $this->userService->getResponseData($k);
                $selfRank[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
                $selfRank[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
                $selfRank[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
                $selfRank[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
                $selfRank[$k]['point'] = $v;
                $selfRank[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
                $selfRank[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
                $selfRank[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
                $selfRank[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
            }
            $selfRank = array_values($selfRank);
            foreach($selfRank as $k=>$v){
                $selfRank[$k]['rank'] = $k+1;
            }
            
        }

        $otherRankList = Redis::zrevrangebyscore( $this->crossRoomPkRoomNowPointKey.$otherRoomId,'+inf','-inf',['withscores'=>true , 'limit'=>[0,3]]);
        $otherRank = [];
        if(!empty($otherRankList)){
            foreach($otherRankList as $k=>$v){
                //用户信息
                $userInfo = $this->userService->getResponseData($k);
                $otherRank[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
                $otherRank[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
                $otherRank[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
                $otherRank[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
                $otherRank[$k]['point'] = $v;
                $otherRank[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
                $otherRank[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
                $otherRank[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
                $otherRank[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
            }
            $otherRank = array_values($otherRank);
            foreach($otherRank as $k=>$v){
                $otherRank[$k]['rank'] = $k+1;
            }
           
        }
        $from_point = $this->crossRoomPkModel->getPointCount($roomId,$pkStart,$pkEnd);
        $otherRoomPoint = $this->crossRoomPkModel->getPointCount($otherRoomId,$pkStart,$pkEnd);

        //获取自己房间下主播收礼情况
        $selfPointList = Redis::zrevrangebyscore( $this->crossRoomPkGetGiftUserPointKey.$roomId,'+inf','-inf',['withscores'=>true , 'limit'=>[0,8]]);
        if(!empty($selfPointList)){
            foreach($selfPointList as $user=>$point){
                $pointList[$user]['user_id'] = $user;
                $pointList[$user]['point'] = $point;
            }
            $selfPointList = array_values($pointList);
        }
        return [
            'selfRoomPoint' => $from_point,
            'otherRoomPoint' => $otherRoomPoint,
            'selfRank' => empty($selfRank) ? [] : $selfRank,
            'otherRank' => empty($otherRank) ? [] : $otherRank,
            'selfPointList' => $selfPointList, //我发主播收礼情况
        ];
    }
    //房间缓存
    public function redisSaveRoomData($roomDayRedisKey, $roomTotal, $roomId, $roomWeekRedisKey){
        //房间日榜榜缓存
        if(Redis::EXISTS($roomDayRedisKey)){
            Redis::ZINCRBY($roomDayRedisKey,$roomTotal,$roomId);
        }else{
            Redis::ZINCRBY($roomDayRedisKey,$roomTotal,$roomId);
            Redis::EXPIRE($roomDayRedisKey,86400);//1天
        }

        //房间周榜
        if(Redis::EXISTS($roomWeekRedisKey)){
            Redis::ZINCRBY($roomWeekRedisKey,$roomTotal,$roomId);
        }else{
            Redis::ZINCRBY($roomWeekRedisKey,$roomTotal,$roomId);
            Redis::EXPIRE($roomWeekRedisKey,7*86400);//7天
        }
    }

    //房间获取PK任务
    public function getUserMission($userId){
        $backSetInfo = $this->crossRoomPkModel->getPkMinutes();
        if(empty($backSetInfo)){
            return [];
        }
        //获取pk开始时间和结束时间
        $endPk = $backSetInfo['pk_end'];
        $startPk = $backSetInfo['pk_start'];
        $now = Carbon::now()->toTimeString();

        if($now >= $startPk && $now <= $endPk){
            $mission = $this->missionIcon;
            $missionGift = $this->crossRoomPkModel->getMissionGift();
            $missionGift = array_column($missionGift,null,'mission_type');
            foreach($mission as &$v){
                $goodInfo = $this->mall_model->getMallGoodByGoodsId($missionGift[$v['type']]['goods_id']);
                $v['gift_name'] = $goodInfo['goods_name'];
            }
            //获取是否完成任务
            $data = $this->crossRoomPkModel->getMissionStatus($userId);
            if(!empty($data)){
                $data = array_column($data,null,'mission_type');
                foreach($mission as &$v){
                    $v['is_complate'] = isset($data[$v['type']]) ? 1 : 0;
                    $v['is_get'] = isset($data[$v['type']]) ? $data[$v['type']]['send_status'] : 0;
                    $v['award_id'] = $data[$v['type']]['id'];
                    
                }
            }
            return $mission;
        }else{
            return [];
        }
    }

    //领取每日任务奖励
    public function getPkAward($userId, $awardId){
        $awardInfo = $this->crossRoomPkModel->getMissionInfo($userId, $awardId);
        do{
            $code = Hint::SUCCESS;
            $msg = 'ok';
            if(empty($awardInfo)){
                $code = Hint::ERR_NORMAL;
                $msg = '未完成任务';
                break;
            }
            //发放头像,气泡
            $goodInfo = $this->mall_model->getMallGoodByGoodsId($awardInfo['goods_id']);
            $skuList = $this->mall_model->getSkuDataByGoods($awardInfo['goods_id']);
            $timeLimit = 1*86400;
            $this->mall_model->shoppingAct(
                11,
                $userId,
                $awardInfo['goods_id'],
                $goodInfo['goods_name'],
                $goodInfo['goods_type'],
                $skuList[0]['sku_id'],
                $timeLimit,
                0,
                $timeLimit,
                time(),
                2
            );
            //更新记录
            $this->crossRoomPkModel->updateMission($awardId);
        }while(false);
        return compact('code','msg');
    }

    //获取排行榜
    public function getRank($type, $week, $roomId, $userId){
        //今日开始-结束
        $today = Carbon::today()->toDateString();
        //一周开始-结束
        $weekStart = Carbon::today()->startOfWeek()->toDateString();
        $weekEnd =  Carbon::today()->endOfWeek()->toDateString();
        //房间缓存key
        $roomDayRedisKey = $this->crossRoomDayPointKey.$today;

        $roomWeekRedisKey = $this->crossRoomWeekPointKey.$weekStart.'-'.$weekEnd;
        //用户缓存key
        $crossRoomUserDayPointKey = $this->crossRoomUserDayPointKey.$today;
        $crossRoomUserWeekPointKey = $this->crossRoomUserWeekPointKey.$weekStart.'-'.$weekEnd;
        $finalArr = [];
        
        //房间榜
        if($type == 1){
            $finalArr = $this->getRoomRank($week, $roomDayRedisKey, $roomWeekRedisKey);
            //我当前房间所在的等级
            $myLevel = $this->myRoomLevel($roomId, $week, $roomDayRedisKey, $roomWeekRedisKey);
        }else{
            //用户榜
            $finalArr = $this->getUserRank($week, $crossRoomUserDayPointKey, $crossRoomUserWeekPointKey);
            $myLevel = $this->myUserLevel($userId, $week, $crossRoomUserDayPointKey,$crossRoomUserWeekPointKey);
        }

        $returnData = array_values($finalArr);
        //排名更新
        foreach($returnData as $k =>$val)
        {
            $returnData[$k]['rank'] = $k+1;
        }
        $data['rankInfo'] = $returnData;
        $data['myrank'] = $myLevel;
        return $data;
    }

    //房间榜获取
    public function getRoomRank($week, $roomDayRedisKey, $roomWeekRedisKey){
        $newData = [];
        //房间榜
        if($week == 1){
            //日榜
            $allSort = Redis::zrevrangebyscore( $roomDayRedisKey,'+inf','-inf',['withscores'=>true , 'limit'=>[0,200]]);
            if(!empty($allSort)){
                foreach($allSort as $k=>$v){
                    //房间信息
                    $roomInfo = $this->roomModel->get_room($k);
                    $newData[$k]['name'] = empty($roomInfo['name']) ? '' : $roomInfo['name'];
                    $newData[$k]['id'] = empty($roomInfo['room_id']) ? '' : $roomInfo['room_id'];
                    $newData[$k]['uuid'] = empty($roomInfo['room_uid']) ? 0 : $roomInfo['room_uid'];
                    $newData[$k]['img'] = empty($roomInfo['image']) ? '' : $roomInfo['image'];
                    $newData[$k]['point'] = $v;
                    $newData[$k]['wealth_balance'] = 0;
                    $newData[$k]['charm_balance'] = 0;
                    $newData[$k]['game_balance'] = 0;
                    $newData[$k]['gender'] = 0;
                } 
            }
        }else{
            //周榜
            $allSort = Redis::zrevrangebyscore( $roomWeekRedisKey,'+inf','-inf',['withscores'=>true , 'limit'=>[0,200]]);
            if(!empty($allSort)){
                foreach($allSort as $k=>$v){
                    //房间信息
                    $roomInfo = $this->roomModel->get_room($k);
                    $newData[$k]['name'] = empty($roomInfo['name']) ? '' : $roomInfo['name'];
                    $newData[$k]['id'] = empty($roomInfo['room_id']) ? '' : $roomInfo['room_id'];
                    $newData[$k]['uuid'] = empty($roomInfo['room_uid']) ? 0 : $roomInfo['room_uid'];
                    $newData[$k]['img'] = empty($roomInfo['image']) ? '' : $roomInfo['image'];
                    $newData[$k]['point'] = $v;
                    $newData[$k]['wealth_balance'] = 0;
                    $newData[$k]['charm_balance'] = 0;
                    $newData[$k]['game_balance'] = 1;
                    $newData[$k]['gender'] = 0;
                } 
            }
        }
        return $newData;
    }

    //我所在房间榜所在楼层
    public function myRoomLevel($roomId, $week, $roomDayRedisKey, $roomWeekRedisKey){
        //日榜
        $myLevelScore = 0;
        if($week == 1){
            $nowlevel = Redis::ZREVRANK($roomDayRedisKey,$roomId);
            //我目前值
            $myLevelScore = Redis::ZSCORE($roomDayRedisKey,$roomId);
    
            if(is_null($nowlevel)){
                $level = '未上榜'; //目前排名
            }elseif($nowlevel == 0){
                $level = 1; //目前排名
            }elseif($nowlevel > 200){
                $level = '200+'; //目前排名
            }else{
                $level = $nowlevel+1;//默认第一名从0开始要加1后面的
            }

        }else{
            $nowlevel = Redis::ZREVRANK($roomWeekRedisKey,$roomId);
            //我目前值
            $myLevelScore = Redis::ZSCORE($roomWeekRedisKey,$roomId);
    
            if(is_null($nowlevel)){
                $level = '未上榜'; //目前排名
            }elseif($nowlevel == 0){
                $level = 1; //目前排名
            }elseif($nowlevel > 200){
                $level = '200+'; //目前排名
            }else{
                $level = $nowlevel+1;//默认第一名从0开始要加1后面的
            }
        }
        //获取房间信息
        $roomInfo = $this->roomModel->get_room($roomId);
        $finaData = [
            'id' => empty($roomInfo['room_id']) ? '' : $roomInfo['room_id'],
            'name' => empty($roomInfo['name']) ? '' : $roomInfo['name'],
            'uuid' => empty($roomInfo['room_uid']) ? '' : $roomInfo['room_uid'],
            'img' => empty($roomInfo['image']) ? '' : $roomInfo['image'],
            'point' => empty($myLevelScore) ? 0 : $myLevelScore,
            'level' => $level,
            'wealth_balance' => 0,
            'charm_balance' => 0,
            'gender' => 0,
        ];
        return $finaData;
    }

    //用户榜获取
    public function getUserRank($week, $crossRoomUserDayPointKey, $crossRoomUserWeekPointKey){
        $newData = [];
        //用户榜
        if($week == 1){
            //日榜
            $allSort = Redis::zrevrangebyscore( $crossRoomUserDayPointKey,'+inf','-inf',['withscores'=>true , 'limit'=>[0,200]]);
            if(!empty($allSort)){
                foreach($allSort as $k=>$v){
                    //用户信息
                    $userInfo = $this->userService->getResponseData($k);
                    $newData[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
                    $newData[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
                    $newData[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
                    $newData[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
                    $newData[$k]['point'] = $v;
                    $newData[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
                    $newData[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
                    $newData[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
                    $newData[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
                } 
            }
        }else{
            //周榜
            $allSort = Redis::zrevrangebyscore( $crossRoomUserWeekPointKey,'+inf','-inf',['withscores'=>true , 'limit'=>[0,200]]);
            if(!empty($allSort)){
                foreach($allSort as $k=>$v){
                    //用户信息
                    $userInfo = $this->userService->getResponseData($k);
                    $newData[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
                    $newData[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
                    $newData[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
                    $newData[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
                    $newData[$k]['point'] = $v;
                    $newData[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
                    $newData[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
                    $newData[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
                    $newData[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
                } 
            }
        }
        return $newData;
    }

    //我的用户排名
    public function myUserLevel($userId, $week, $crossRoomUserDayPointKey,$crossRoomUserWeekPointKey){
        //日榜
        $myLevelScore = 0;
        if($week == 1){
            $nowlevel = Redis::ZREVRANK($crossRoomUserDayPointKey,$userId);
            //我目前值
            $myLevelScore = Redis::ZSCORE($crossRoomUserDayPointKey,$userId);
    
            if(is_null($nowlevel)){
                $level = '未上榜'; //目前排名
            }elseif($nowlevel == 0){
                $level = 1; //目前排名
            }elseif($nowlevel > 200){
                $level = '200+'; //目前排名
            }else{
                $level = $nowlevel+1;//默认第一名从0开始要加1后面的
            }

        }else{
            $nowlevel = Redis::ZREVRANK($crossRoomUserWeekPointKey,$userId);
            //我目前值
            $myLevelScore = Redis::ZSCORE($crossRoomUserWeekPointKey,$userId);
    
            if(is_null($nowlevel)){
                $level = '未上榜'; //目前排名
            }elseif($nowlevel == 0){
                $level = 1; //目前排名
            }elseif($nowlevel > 200){
                $level = '200+'; //目前排名
            }else{
                $level = $nowlevel+1;//默认第一名从0开始要加1后面的
            }
        }
        //获取用户信息
        $userInfo = $this->userService->getResponseData($userId);
        $finaData = [
            'id' => empty($userInfo['user_id']) ? '' : $userInfo['user_id'],
            'name' => empty($userInfo['nickname']) ? '' : $userInfo['nickname'],
            'uuid' => empty($userInfo['user_uid']) ? '' : $userInfo['user_uid'],
            'img' =>  empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0],
            'point' => empty($myLevelScore) ? 0 : $myLevelScore,
            'level' => $level,
            'wealth_balance' => empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'],
            'charm_balance' => empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'],
            'game_balance' => empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'],
            'gender' => empty($userInfo['gender']) ? 1 : $userInfo['gender'],
        ];
        return $finaData;
    }

    //获取PK实时榜单
    public function getNowRank($roomId, $userId){
        //pk信息
        $pkInfo = $this->crossRoomPkModel->issetPkRecord($roomId);
        //榜单获取
        $list = Redis::zrevrangebyscore($this->crossRoomPkRoomNowPointKey.$roomId,'+inf','-inf',['withscores'=>true , 'limit'=>[0,200]]);
        //获取总共参与人数
        $count = $this->crossRoomPkModel->getNowRankUser($roomId, $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
        foreach($list as $k=>$v){
            //用户信息
            $userInfo = $this->userService->getResponseData($k);
            $newData[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
            $newData[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
            $newData[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
            $newData[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
            $newData[$k]['point'] = $v;
            $newData[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
            $newData[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
            $newData[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
            $newData[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
        } 
        $newData = array_values($newData);
        foreach($newData as $k=>$v){
            $newData[$k]['rank'] = $k+1;
        }
        //获取我的排名
        $nowlevel = Redis::ZREVRANK($this->crossRoomPkRoomNowPointKey.$roomId,$userId);
        //我目前值
        $myLevelScore = Redis::ZSCORE($this->crossRoomPkRoomNowPointKey.$roomId,$userId);

        if(is_null($nowlevel)){
            $level = '未上榜'; //目前排名
        }elseif($nowlevel == 0){
            $level = 1; //目前排名
        }elseif($nowlevel > 200){
            $level = '200+'; //目前排名
        }else{
            $level = $nowlevel+1;//默认第一名从0开始要加1后面的
        }

        //获取用户信息
        $userInfo = $this->userService->getResponseData($userId);
        $finaData = [
            'id' => empty($userInfo['user_id']) ? '' : $userInfo['user_id'],
            'name' => empty($userInfo['nickname']) ? '' : $userInfo['nickname'],
            'uuid' => empty($userInfo['user_uid']) ? '' : $userInfo['user_uid'],
            'img' =>  empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0],
            'point' => empty($myLevelScore) ? 0 : $myLevelScore,
            'level' => $level,
            'wealth_balance' => empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'],
            'charm_balance' => empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'],
            'game_balance' => empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'],
            'gender' => empty($userInfo['gender']) ? 1 : $userInfo['gender'],
        ];
        $data['allUser'] = empty($count['count']) ? 0 : $count['count'];
        $data['list'] = empty($newData) ? [] : $newData;
        $data['mylevel'] = $finaData;
        return $data;
    }

    //获取房间战绩
    public function getRoomRecord($roomId, $page, $limit){
        //获取本周PK总送出钻石数
        $allDiamond = $this->crossRoomPkModel->getWeekRoomDiamond($roomId);
        //获取本周PK总参与人数
        $allUserCount = $this->crossRoomPkModel->getWeekRoomUser($roomId);
        //本周房间贡献榜(显示前4个)
        //房间内参与贡献用户周榜
        $weekStart = Carbon::today()->startOfWeek()->toDateString();
        $weekEnd =  Carbon::today()->endOfWeek()->toDateString();
        $crossRoomWeekUserPointKey = $this->crossRoomWeekInRoomUserPointKey.$roomId.":".$weekStart.'-'.$weekEnd;
        $weekRank = Redis::zrevrangebyscore( $crossRoomWeekUserPointKey,'+inf','-inf',['withscores'=>true , 'limit'=>[0,4]]);;
        $newData = [];
        if(!empty($weekRank)){
            foreach($weekRank as $k=>$v){
                //用户信息
                $userInfo = $this->userService->getResponseData($k);
                $newData[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
                $newData[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
                $newData[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
                $newData[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
                $newData[$k]['point'] = $v;
                $newData[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
                $newData[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
                $newData[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
                $newData[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
                
            }
            $newData = array_values($newData);
            foreach($newData as $k=>$v){
                $newData[$k]['rank'] = $k+1;
            }
        }
        //历史战绩
        $pkHistory = $this->crossRoomPkModel->getPkHistory($roomId, $page, $limit);
        $pkHistoryList = [];
        if(!empty($pkHistory)){
            foreach($pkHistory as $key=>$pk){
                if($pk['winner_room_id'] == $roomId){
                    $pkHistoryList[$key]['pk_status'] = 1;//pk 状态1=胜利 2=失败 3=平局
                    $point = $this->crossRoomPkModel->getPointCount($roomId, $pk['pk_start_time'], $pk['pk_end_time']);
                    $pkHistoryList[$key]['point'] = $point; //本次PK获得分数
                }else{
                    $pkHistoryList[$key]['pk_status'] = 2;
                    $point = $this->crossRoomPkModel->getPointCount($roomId, $pk['pk_start_time'], $pk['pk_end_time']);
                    $pkHistoryList[$key]['point'] = $point;
                    if($pk['pk_status'] == 3){
                        $pkHistoryList[$key]['pk_status'] = 3;   
                        $pkHistoryList[$key]['point'] = $pk['red_point']; 
                    }    
                }
                $roomInfo = $this->roomModel->get_room($roomId);
                $pkHistoryList[$key]['id'] = $pk['id'];
                $pkHistoryList[$key]['pk_end_time'] = $pk['pk_end_time'];//结束时间
                $pkHistoryList[$key]['room_name'] = $roomInfo['name'];//房间名称
                $pkHistoryList[$key]['room_img'] = $roomInfo['image'];//房间图片
            }
        }
        //整理
        $returnData = [
            'allDiamond' => $allDiamond,//房间总送出钻石
            'allUserCount' => empty($allUserCount['count']) ? 0 : $allUserCount['count'],//总参加人数
            'rank' => $newData,//周榜
            'history' => $pkHistoryList,//历史数据
        ];
        return $returnData;
    }

    //获取自己房间本周参与人数排行
    public function getSelfRoomRank($roomId, $userId){
        $newData = [];
        //一周开始-结束
        $weekStart = Carbon::today()->startOfWeek()->toDateString();
        $weekEnd =  Carbon::today()->endOfWeek()->toDateString();
        //单个房间内参与贡献用户周榜
        $crossRoomWeekInRoomUserPointKey = $this->crossRoomWeekInRoomUserPointKey.$roomId.":".$weekStart.'-'.$weekEnd;
        //周榜
        $allSort = Redis::zrevrangebyscore($crossRoomWeekInRoomUserPointKey,'+inf','-inf',['withscores'=>true , 'limit'=>[0,200]]);
        //获取本周PK总参与人数
        $allUserCount = $this->crossRoomPkModel->getWeekRoomUser($roomId);
        if(!empty($allSort)){
            foreach($allSort as $k=>$v){
                //用户信息
                $userInfo = $this->userService->getResponseData($k);
                $newData[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
                $newData[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
                $newData[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
                $newData[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
                $newData[$k]['point'] = $v;
                $newData[$k]['wealth_balance'] = empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'];
                $newData[$k]['charm_balance'] = empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'];
                $newData[$k]['game_balance'] = empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'];
                $newData[$k]['gender'] = empty($userInfo['gender']) ? 1 : $userInfo['gender'];
            } 
        }
        if(!empty($newData)){
            $newData = array_values($newData);
            foreach($newData as $k=>$v){
                $newData[$k]['rank'] = $k+1;
            }
        }
        //获取登录用户所在排名
        $nowlevel = Redis::ZREVRANK($crossRoomWeekInRoomUserPointKey,$userId);
        //我目前值
        $myLevelScore = Redis::ZSCORE($crossRoomWeekInRoomUserPointKey,$userId);

        if(is_null($nowlevel)){
            $level = '未上榜'; //目前排名
        }elseif($nowlevel == 0){
            $level = 1; //目前排名
        }elseif($nowlevel > 200){
            $level = '200+'; //目前排名
        }else{
            $level = $nowlevel+1;//默认第一名从0开始要加1后面的
        }
        //获取用户信息
        $userInfo = $this->userService->getResponseData($userId);
        $finaData = [
            'id' => empty($userInfo['user_id']) ? '' : $userInfo['user_id'],
            'name' => empty($userInfo['nickname']) ? '' : $userInfo['nickname'],
            'uuid' => empty($userInfo['user_uid']) ? '' : $userInfo['user_uid'],
            'img' =>  empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0],
            'point' => empty($myLevelScore) ? 0 : $myLevelScore,
            'level' => $level,
            'wealth_balance' => empty($userInfo['wealth_balance']) ? 0 : $userInfo['wealth_balance'],
            'charm_balance' => empty($userInfo['charm_balance']) ? 0 : $userInfo['charm_balance'],
            'game_balance' => empty($userInfo['game_balance']) ? 1 : $userInfo['game_balance'],
            'gender' => empty($userInfo['gender']) ? 1 : $userInfo['gender'],
        ];
        $returnData['list'] = $newData;
        $returnData['allUser'] = empty($allUserCount['count']) ? 0 : $allUserCount['count'];
        $returnData['mylevel'] = $finaData;
        return $returnData;
    }

    //PK结算接口
    public function endPk($sendId, $type, $roomId, $userId){
        //查询次记录的PK信息
        $pkInfo = $this->crossRoomPkModel->getPkInfo($sendId);
        do{
            $code = Hint::SUCCESS;
            $msg = 'ok';
            $data = [];

            if(empty($pkInfo)){
                $code = Hint::ERR_NORMAL;
                $msg = 'pk记录不存在';
                break;
            }

            if($pkInfo['pk_status'] != 4){
                $code = Hint::ERR_NORMAL;
                $msg = 'pk已结算';
                break;
            }

            //获取用户权限
            $role = $this->checkRoomAdmin($userId, $roomId);
            
            if(in_array($role,[1,2])){
                //防止多次结算
                redis_lock($this->endPkRedisKey.$sendId,10);
                $finaData = $this->endpkData($pkInfo,$type, $roomId);  
                try{
                    //更新预备数组
                    $update = [
                        'pk_status' => $finaData['pk_status'],
                        'red_point' => $finaData['red_point'],
                        'blue_point' => $finaData['blue_point'],
                        'winner_room_id' => $finaData['winner_room_id'],
                        'updated_at' => Carbon::now()->toDateTimeString(),
                    ];
                    $status = $this->crossRoomPkModel->endPk($sendId, $update);

                    //更新房间模式恢复正常
                    $roomModel['room_mode'] = 1;
                    $this->crossRoomPkModel->updateRoomModel([$pkInfo['from_room_id'],$pkInfo['to_room_id']],$roomModel);
                    $this->roomModel->setRoomOpenListCache($pkInfo['from_room_id'],'roomMode',1);
                    $this->roomModel->setRoomOpenListCache($pkInfo['to_room_id'],'roomMode',1);

                    //当天连胜缓存
                    $winnerTime = 0;
                    if($finaData['winner_room_id'] != 0){
                        $winnCountReids = $this->crossRoomWinnerRoomCount.$finaData['winner_room_id'];
                        if($finaData['winner_room_id'] == $pkInfo['from_room_id']){
                            $failId = $pkInfo['to_room_id'];
                        }else{
                            $failId = $pkInfo['from_room_id'];
                        }
                        if(Redis::EXISTS($winnCountReids)){
                            Redis::INCRBY($winnCountReids,1);
                            Redis::DEL($this->crossRoomWinnerRoomCount.$failId);
                        }else{
                            Redis::INCRBY($winnCountReids,1);
                            //计算结束当天所差秒数
                            $now = Carbon::now()->toDateTimeString();
                            $endDay = Carbon::now()->endOfDay()->toDateTimeString();
                            $diffTime = Carbon::parse($now)->diffInSeconds($endDay);
                            Redis::EXPIRE($winnCountReids,$diffTime);//当天结束时间秒数
                            Redis::DEL($this->crossRoomWinnerRoomCount.$failId);//删除失败方的记录
                        }
                        //获取连胜次数
                        $winnerTime = Redis::get($winnCountReids);
                        //获取参与用户积分总情况
                        $joinUserData = $this->crossRoomPkModel->getJoinUserData([$finaData['winner_room_id']], $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);

                        //每日获胜PK任务
                        $joinUserIds = array_column($joinUserData,'from_user_id');
                        //筛选主播
                        $anchorUserId = $this->model_union_user->getUnionByUser($joinUserIds);
                        $missList = $this->crossRoomPkModel->getMissionGift();
                        $missList = array_column($missList,null,'mission_type');
                        if(!empty($anchorUserId)){
                            $anchorUserIdArr = array_column($anchorUserId,'user_id');
                            foreach($anchorUserIdArr as $k=>$v){
                                $this->finishJob($v, $missList);   
                            }  
                        }
                        //检查麦上用户
                        $micList = $this->roomService->microUserList(['room_id'=>$finaData['winner_room_id']]);
                        if($micList['code'] == 0){
                            //主播id
                            $hostUserId = $micList['data']['host_micro']['user_id'];
                            $this->finishJob($hostUserId, $missList);
                            $anchorList = array_column($micList['data']['general_micro_list'],'user_id');
                            foreach($anchorList as $user){
                                $this->finishJob($user, $missList);
                            }
                        }
                    }  
                    
                    DB::commit();
                }catch (\Exception $e) {
                    DB::rollBack();
                    write_log($this->error_log,'ERROR 数据处理失败',['msg'=>$e->getMessage(),'line'=>$e->getLine(),'data'=>$update,'sendId'=>$sendId]);
                }  
                if($status){
                    //给发起方发信息
                    if($pkInfo['from_room_id'] == $roomId){
                        $point = [
                            'self_point' => $finaData['red_point'],
                            'other_point' => $finaData['blue_point'],
                        ];
                        $otherPoint = [
                            'self_point' => $finaData['blue_point'],
                            'other_point' => $finaData['red_point'],
                        ];
                    }else{
                        $point = [
                            'self_point' => $finaData['blue_point'],
                            'other_point' => $finaData['red_point'],
                        ];
                        $otherPoint = [
                            'self_point' => $finaData['red_point'],
                            'other_point' => $finaData['blue_point'],
                        ];
                    }
                    
                    //房间信息
                    $fromRoomInfo = $this->roomModel->get_room($pkInfo['from_room_id']);
                    $toRoomInfo = $this->roomModel->get_room($pkInfo['to_room_id']);

                    //参与发起方人送礼记录
                    $fromJoin = $this->crossRoomPkModel->getJoinUserData([$pkInfo['from_room_id']], $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
                    $msg = $this->service_msg->end_cross_pk_msg($pkInfo['from_room_id'], $fromJoin,$finaData['winner_room_id'], $winnerTime, $point, $fromRoomInfo['image'], $toRoomInfo['image'], $finaData['pk_status']);
                    
                    //参与对方人送礼记录
                    $toJoin = $this->crossRoomPkModel->getJoinUserData([$pkInfo['to_room_id']], $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
                    $tomsg = $this->service_msg->end_cross_pk_msg($pkInfo['to_room_id'], $toJoin,$finaData['winner_room_id'], $winnerTime, $otherPoint, $toRoomInfo['image'], $fromRoomInfo['image'], $finaData['pk_status']);

                    //发送房间公屏消息
                    $winmsg = '本场pk胜利，继续加油';
                    $failmsg = '本场pk失败，继续加油';
                    $bothmsg = '本场pk平局，继续加油';
                    if($finaData['winner_room_id'] != 0){
                        $winnerMsg = $this->service_msg->pk_status_msg($finaData['winner_room_id'],$winmsg);
                        $failMsg = $this->service_msg->pk_status_msg($failId,$failmsg);
                    }else{
                        $winnerMsg = $this->service_msg->pk_status_msg($pkInfo['from_room_id'],$bothmsg);
                        $failMsg = $this->service_msg->pk_status_msg($pkInfo['to_room_id'],$bothmsg);
                    }
                    
                    
                }else{
                $code = Hint::ERR_DB_FAIL;
                $msg = '更新失败';
                break; 
                }
            }   
        }while(false);
        return compact('code','msg','data');
    }
    
    //pk胜利任务
    public function finishJob($userId,$missList){
        if(empty(Redis::get($this->missionPkAnchorKey.$userId))){
            $insertMission = [
                'user_id' => $userId,
                'mission_type' => 4,//任务类型 1=PK送礼 2=上麦任务 3=发言 4=PK胜利
                'goods_id' => $missList[4]['goods_id'],
                'send_status'=> 0,
                'created_at' => Carbon::now()->toDateTimeString(),
            ];
            $this->crossRoomPkModel->insertMission($insertMission);
            
            //计算结束当天所差秒数
            $now = Carbon::now()->toDateTimeString();
            $endDay = Carbon::now()->endOfDay()->toDateTimeString();
            $diffTime = Carbon::parse($now)->diffInSeconds($endDay);
            Redis::SET($this->missionPkAnchorKey.$userId,1);
            Redis::EXPIRE($this->missionPkAnchorKey.$userId,$diffTime);//当天结束时间秒数
        }
    }

    //pk结算数据逻辑
    public function endpkData($pkInfo, $type, $roomId){
        //查询流水记录
        $firstRoomStream = $this->crossRoomPkModel->getPointCount($pkInfo['from_room_id'], $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);
        $secondRoomStream = $this->crossRoomPkModel->getPointCount($pkInfo['to_room_id'], $pkInfo['pk_start_time'], $pkInfo['pk_end_time']);

        //提前结束PK
        if($type == 1){
           if($pkInfo['from_room_id'] == $roomId){
             $winnerRoom = $pkInfo['to_room_id'];
             $pk_status = 2;//失败
             $selfPoint = $firstRoomStream;
             $otherPoint = $secondRoomStream;
             $fromId = $roomId;
             $toId = $pkInfo['to_room_id'];
           }else{
             $winnerRoom = $pkInfo['from_room_id'];
             $pk_status = 2;//失败
             $selfPoint = $secondRoomStream;
             $otherPoint = $firstRoomStream;
             $fromId = $roomId;
             $toId = $pkInfo['from_room_id'];
           }
        }else{
            if($pkInfo['from_room_id']  == $roomId){
                $selfPoint = $firstRoomStream;
                $otherPoint = $secondRoomStream;
                $fromId = $roomId;
                $toId = $pkInfo['to_room_id'];
            }else{
                $selfPoint = $secondRoomStream;
                $otherPoint = $firstRoomStream;
                $fromId = $roomId;
                $toId = $pkInfo['from_room_id'];
            }
            //大小比较
            if($firstRoomStream > $secondRoomStream){
                $winnerRoom = $pkInfo['from_room_id'] ;//胜利房间id
                $pk_status = 1;//胜利
            }elseif($firstRoomStream < $secondRoomStream){
                $winnerRoom = $pkInfo['to_room_id'] ;//胜利房间id
                $pk_status = 2;//失败
            }else{
                $winnerRoom = 0;//胜利房间id
                $pk_status = 3;//平局
            }
        }
        
        return [
            'pk_status' => $pk_status,
            'red_point' => $selfPoint,
            'blue_point' => $otherPoint,
            'fromId' => $fromId,
            'toId' => $toId,
            'winner_room_id' => $winnerRoom,
        ];
    }

    //我的PK
    public function myPk($userId,$roomId){
        //获取我参与过的房间PK记录
        $allPkRoom = $this->crossRoomPkModel->getPkList($roomId);
        $finalData = [];
        if(!empty($allPkRoom)){
            //整理数据
            foreach($allPkRoom as $k=>$v){
                //查询房间信息
                $fromRoomInfo = $this->roomModel->get_room($v['from_room_id']);
                $toRoomInfo = $this->roomModel->get_room($v['to_room_id']);
                $finalData[$k]['from_img'] = $fromRoomInfo['image'];//发起方图片
                $finalData[$k]['from_name'] = $fromRoomInfo['name'];//发起方房间名称
                $finalData[$k]['to_name'] = $toRoomInfo['name'];//接受方名称
                $finalData[$k]['to_img'] = $toRoomInfo['image'];//接受方图片
                $finalData[$k]['pk_time'] = $v['pk_end_time'];//PK结束时间
                $finalData[$k]['id']= $v['id'];
                //获取我参与房间的pk值
                $finalData[$k]['pk_point'] = $this->crossRoomPkModel->getPointCount($roomId,$v['pk_start_time'],$v['pk_end_time']);
                $myPoint = $this->crossRoomPkModel->getPointMy($userId, $roomId, $v['pk_start_time'],$v['pk_end_time']);
                $finalData[$k]['my_point'] =  empty($myPoint['total']) ? 0 : $myPoint['total'];//我送礼积分
                //我的排名
                $level = $this->getUserInRoomRank($roomId, $userId, $v['pk_start_time'],$v['pk_end_time'],$v);
                $finalData[$k]['my_level'] = $level;
                
            }
        }
        return $finalData;
    }

    //获取用户在房间的排名
    public function getUserInRoomRank($roomId, $userId, $pkStart, $pkEnd, $v){
        //获取我在房间内的排名
        $ranklist = $this->crossRoomPkModel->getNowRank($roomId, $pkStart, $pkEnd);
        //获取我的排名
        $searchArr = array_column($ranklist,'from_user_id');
        
        $nowlevel = array_search($userId,$searchArr);
        
        if($nowlevel === false){
            $level = '未上榜'; //目前排名
        }elseif($nowlevel == 0){
            $level = '贡献榜1名'; //目前排名
        }elseif($nowlevel > 200){
            $level = '贡献榜200+'; //目前排名
        }else{
            $level = '贡献榜'. $nowlevel+1 .'名';//默认第一名从0开始要加1后面的
        }
        return $level;
    }
    
    //进入房间时候获取PK房间数据
    public function getJoinPkInfo($roomId){
        do{
            $code = Hint::SUCCESS;
            $msg = 'ok';
            $data = [];
            //获取双方PK值
            $pkInfo = $this->crossRoomPkModel->issetPkRecord($roomId);
            if(empty($pkInfo)){
                $code = Hint::ERR_NORMAL;
                $msg = 'PK记录不存在';
                break;
            }
            if($pkInfo['pk_status'] != 4){
                $code = Hint::ERR_NORMAL;
                $msg = '暂未发起PK';
                break;
            }
            //邀请方值
            $from_point = $this->crossRoomPkModel->getPointCount($pkInfo['from_room_id'],$pkInfo['pk_start_time'],$pkInfo['pk_end_time']);
            $to_roompoint = $this->crossRoomPkModel->getPointCount($pkInfo['to_room_id'],$pkInfo['pk_start_time'],$pkInfo['pk_end_time']);
            
            //获取双方房间自己房间内排行前三数据
            $from_list = $this->getThreeTopInfo($pkInfo['from_room_id'],$pkInfo['pk_start_time'],$pkInfo['pk_end_time']);
            $to_list = $this->getThreeTopInfo($pkInfo['to_room_id'],$pkInfo['pk_start_time'],$pkInfo['pk_end_time']);

            //进入房间主播收礼值
            $selfPointList = Redis::zrevrangebyscore( $this->crossRoomPkGetGiftUserPointKey.$roomId,'+inf','-inf',['withscores'=>true , 'limit'=>[0,8]]);
            if(!empty($selfPointList)){
                foreach($selfPointList as $user=>$point){
                    $pointList[$user]['user_id'] = $user;
                    $pointList[$user]['point'] = $point;
                }
                $selfPointList = array_values($pointList);
            }

            //进入房间判断 
            if($pkInfo['from_room_id'] == $roomId){
                $selfRoomPoint = $from_point;
                $otherRoomPoint = $to_roompoint;
                $selfRank = $from_list;
                $otherRank = $to_list;
                //进入房间信息
                $doubleRoomInfo = $this->getDoubleRoomInfo($pkInfo['from_room_id'],$pkInfo['to_room_id']);
            }else{
                $selfRoomPoint = $to_roompoint;
                $otherRoomPoint = $from_point;
                $selfRank = $to_list;
                $otherRank = $from_list;
                //进入房间信息
                $doubleRoomInfo = $this->getDoubleRoomInfo($pkInfo['to_room_id'],$pkInfo['from_room_id']);
            }
            
            $data = [
                'selfRoomPoint' => $selfRoomPoint, //我发收礼总值
                'otherRoomPoint' => $otherRoomPoint, //对方收礼总值
                'selfRank' => empty($selfRank) ? [] : $selfRank, //我方排名
                'otherRank' => empty($otherRank) ? [] : $otherRank,  //对方前三排名
                'pk_start_time' => strtotime($pkInfo['pk_start_time']), //开始时间
                'pk_end_time' => strtotime($pkInfo['pk_end_time']),//结束时间
                'myRoomInfo' => $doubleRoomInfo['myRoomInfo'], //我方房间信息
                'otherRoomInfo' => $doubleRoomInfo['otherRoomInfo'], //对方房间信息
                'selfPointList' => $selfPointList, //我发主播收礼情况
                'send_id' => $pkInfo['id'],//邀请id
                'now_time' => time(),
            ];
        }while(false);
    
        return compact('code','msg','data');
    }
    
    //获取用户前三数据信息
    public function getThreeTopInfo($roomId, $pkStartTime, $pkEndTime){
        $data = $this->crossRoomPkModel->getNowRank($roomId,$pkStartTime,$pkEndTime,3);
                
        foreach($data as $k=>$v){
            //用户信息
            $userInfo = $this->userService->getResponseData($v['from_user_id']);
            $topData[$k]['name'] = empty($userInfo['nickname']) ? '' : $userInfo['nickname'];
            $topData[$k]['id'] = empty($userInfo['user_id']) ? '' : $userInfo['user_id'];
            $topData[$k]['uuid'] = empty($userInfo['user_uid']) ? 0 : $userInfo['user_uid'];
            $topData[$k]['img'] = empty($userInfo['thumbnails']) ? '' : $userInfo['thumbnails'][0];
            $topData[$k]['point'] = $v['point'];
            $topData[$k]['rank'] = $k+1;
        } 
        return $topData;
    }

    //获取双方房间信息
    public function getDoubleRoomInfo($roomId, $toRoomId){
        $myRoomInfo = $this->roomModel->get_room($roomId);
        $myRoomInfo = [
            "name" => empty($myRoomInfo['name']) ? '音洛聊天室' :  $myRoomInfo['name'],
            "img" => $myRoomInfo['image'],
            "room_id" => $myRoomInfo['room_id'],
        ];
        //对方房间信息
        $otherRoomInfo = $this->roomModel->get_room($toRoomId);
        $otherRoomInfo = [
            "name" => empty($otherRoomInfo['name']) ? '音洛聊天室' :  $otherRoomInfo['name'],
            "img" => $otherRoomInfo['image'],
            "room_id" => $otherRoomInfo['room_id'],
        ];
        return ['myRoomInfo'=>$myRoomInfo,'otherRoomInfo'=>$otherRoomInfo];
    }
}